/****************************************Copyright (c)****************************************************
 
**--------------File Info---------------------------------------------------------------------------------
** File name:                key.h
** Last modified Date:       2024.08.07
** Last Version:             Ver:1.0
** Descriptions:             电键处理模块
**                        
**--------------------------------------------------------------------------------------------------------
** Created by:               adm
** Created date:             2024.08.07
** Version:                  Ver:1.0
** Descriptions:             电键处理模块
**
**--------------------------------------------------------------------------------------------------------*/
/*
Copyright (c) [2024]     [BA6IV  ]   [SINEWAVE] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan
PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/

#include "key.h"

// Function define zone
void KeyInit(void);
void Di(void);
void Da(void);


//定义一个电键对象，并初始化一些必要的初值
MorseKey_type_t MyKey = {
    .KeyEnable_Flag = 1,            //电键使能标志置位
    .KEY_Mode       = paddle,       //straight:手键    paddle:自动键
    .speed          = 20,           //自动键速度
    .tone           = 600,          //电码音调
    .tone_volume    = 50,           //电码音调音量
    .Autokey_change = normal,       //自动键点划方向正常
    .di_flag        = 0,            //自动键 嘀标志清除
    .da_flag        = 0,            //自动键 嗒标志清除
    .KeyInit        = KeyInit,
    .Di             = Di,
    .Da             = Da,
};



//电键初始化函数，根据配置参数初始化电键端口
void KeyInit(void)
{
    gpio_init_type gpio_init_struct;
    gpio_default_para_init(&gpio_init_struct);

    /* 电键、按钮输入端口初始化 */
    gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
    gpio_init_struct.gpio_pins = KEY_L_PIN | KEY_R_PIN;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
    gpio_init(GPIOA, &gpio_init_struct);

    /* LED端口初始化 */
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pins = LED_PIN;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(LED_GPIO_PORT, &gpio_init_struct);
    

//    LED_ON();                               //LED亮
    
    /* 电键类型开机自动识别（通过手键插头中间环对地实现自动识别） */
    if((Read_KEY_L() == RESET) && (Read_KEY_R() == RESET)) {    //开机时顶段、中段同时短路，设置为自动键，但是点划交换；否则设置为自动键，点划不交换
        delay_ms(30);
        if((Read_KEY_L() == RESET) && (Read_KEY_R() == RESET)) {
            MyKey.Autokey_change = inversion;
        }
    }
    else if(Read_KEY_L() == RESET) {             //开机时中段短路，设置为手键
        delay_ms(30);
        if(Read_KEY_L() == RESET) {
            MyKey.KEY_Mode = straight;
            MyKey.Autokey_change = inversion;
        }
    }
    else if(Read_KEY_R() == RESET) {            //开机时顶段短路，设置为手键
        delay_ms(30);
        if(Read_KEY_R() == RESET) {
            MyKey.KEY_Mode = straight;
            MyKey.Autokey_change = inversion;
        }
    }
}

//嘀函数
void Di(void)
{
    Tone_ON();                              //音频开启
    LED_ON();
    delay_ms(1200 / MyKey.speed);

    Tone_OFF();                             //音频关闭
    LED_OFF();
    delay_ms(1200 / MyKey.speed);
}

//嗒函数
void Da(void)
{
    Tone_ON();                              //音频开启
    LED_ON();
    delay_ms(3 * (1200 / MyKey.speed));     //普通延时

    Tone_OFF();                             //音频关闭
    LED_OFF();
    delay_ms(1200 / MyKey.speed);
}


void Di_num(uint8_t count)
{
    while(count--) {
        Di();
    }
}

//字符间隔
void Char_Space(void)
{
    delay_ms(3 * (1200 / MyKey.speed));
}

//单词间隔
void Word_Space(void)
{
    delay_ms(5 * (1200 / MyKey.speed));
}


//电键按下检测服务例程，此函数应放到滴答中断内定时运行
void KeyCheckFun(void)
{
    static uint16_t Dikey_Delay;            //定义按键延时静态变量
    static uint16_t Dakey_Delay;            //定义按键延时静态变量
    static uint16_t Tim_Count;              //定义计数器变量

    Tim_Count++;                //计数器变量累加


    if (MyKey.KEY_Mode > 0) {        //判断电键的设置类型
        //进入自动键处理流程
        if (Read_KEY_L() != 1) {  //判断左键是否按下
            Dikey_Delay++;
            if (Dikey_Delay >= Key_Delay) {     //判断按键延时是否到预设值*1ms
                if (MyKey.Autokey_change) {        //检查自动键左右方向标志位
                    MyKey.di_flag = 1;                                  //Di标志位置位
                } else {
                    MyKey.da_flag = 1;                                  //Da标志位置位
                }

                Dikey_Delay = 0;                            //按键延时静态变量清零
            }
        }

        if (Read_KEY_R() != 1) {     //判断右键是否按下
            Dakey_Delay++;
            if (Dakey_Delay >= Key_Delay) {     //判断按键延时是否到预设值*1ms
                if (MyKey.Autokey_change) {        //检查自动键左右方向标志位
                    MyKey.da_flag = 1;                                  //Di标志位置位
                } else {
                    MyKey.di_flag = 1;                                  //Da标志位置位
                }

                Dakey_Delay = 0;                            //按键延时静态变量清零
            }
        }
    } else {                            //键入手键处理流程(手键不检查点划交换设置，直接检测顶部环电平判断电键按下)
//        if (MyKey.Autokey_change == normal) {  //判断正常线序手键是否按下
            if (!Read_KEY_R()) {
                Dikey_Delay++;
                if (Dikey_Delay >= Key_Delay) {     //判断按键延时是否到预设值*1ms
                    MyKey.di_flag = 1;                      //Di标志位置位（手键共用自动键标志位）
                    Dikey_Delay = 0;                            //按键延时静态变量清零
                }
            } else {
                MyKey.di_flag = 0;                      //Di标志位置位（手键共用自动键标志位）
                MyKey.da_flag = 0;                      //Da标志位置位（手键共用自动键标志位）
            }
//        } else {  //判断反转线序手键是否按下
//            if (!Read_KEY_L()) { 
//                Dikey_Delay++;
//                if (Dikey_Delay >= Key_Delay) {     //判断按键延时是否到预设值*1ms
//                    MyKey.di_flag = 1;                      //Di标志位置位（手键共用自动键标志位）
//                    Dikey_Delay = 0;                            //按键延时静态变量清零
//                }
//            } else {
//                MyKey.di_flag = 0;                      //Di标志位置位（手键共用自动键标志位）
//                MyKey.da_flag = 0;                      //Da标志位置位（手键共用自动键标志位）
//            }
//        }
    }
}


//电键状态处理函数
void KeyProcessorFun(void)
{
    if (MyKey.KeyEnable_Flag) {         //判断电键是否可以工作
        if (MyKey.KEY_Mode > 0) {        //判断电键的设置类型
            //开始自动键状态处理
            if (MyKey.di_flag == 1) {
                Di();
                MyKey.di_flag = 0;      //嘀标志位复位
            }

            if (MyKey.da_flag == 1) {
                Da();
                MyKey.da_flag = 0;      //嗒标志位复位
            }
        } else {
            //开始手键状态处理
            if (MyKey.di_flag || MyKey.da_flag) {
                Tone_ON();
                LED_ON();
            } else {
                Tone_OFF();
                LED_OFF();
            }
        }
    }
}



